﻿using System;
using System.Collections.Generic;
using System.Text;
using EnCor.Security;
using EnCor.Config;
using EnCor.ServiceLocator;
using EnCor.Logging;

namespace EnCor
{
    public static class Runtime
    {
        #region Private Fields
        private static object InstanceLocker = new object();

        private static EnCorEnviroment _Environment;

        #endregion

        private static void InitRuntime(EnCorConfig config)
        {
            if (_Environment == null)
            {
                lock (InstanceLocker)
                {
                    if (_Environment == null)
                    {
                        try
                        {
                            _Environment = new EnCorEnviroment(config);
                            _Environment.StartUp();
                        }
                        catch (Exception ex)
                        {
                            _Environment = null;
                            ILog log = BaseLogManager.GetLogger("EnCor");
                            log.Fatal("EnCor runtime failed to start.", ex);
                            throw;
                        }
                    }
                }
            }
        }

        public static void InitializeSecurityContext()
        {
            _Environment.InitializeSecurityContext();
        }

        public static T GetService<T>()
        {
            return _Environment.GetService<T>();
        }

        private static Dictionary<string, object> serviceCache = new Dictionary<string, object>();
        public static T GetService<T>(string serviceId)
        {
            return (T)serviceCache[serviceId];
        }

        internal static void RegisterService(string serviceId, object serviceInstance)
        {
            serviceCache.Add(serviceId, serviceInstance);
        }

        public static void Start()
        {
            Start(EnCorConfig.GetConfig());
        }

        public static void Start(EnCorConfig config)
        {
            if (_Environment != null)
            {
                throw new EnCorException("Runtime already started");
            }
            InitRuntime(config);
        }

        public static void Stop()
        {
            if (_Environment != null)
            {
                _Environment.Stop();
                _Environment = null;
            }
        }



        [Obsolete("Please use Runtime.SecurityCenter.Authenticate() for instead")]
        public static AuthenticateToken Authenticate(Credential credential)
        {
            return _Environment.SecurityCenter.Authenticate(credential);
        }

        public static ISecurityCenter SecurityCenter
        { 
            get
            {
                return _Environment.SecurityCenter;
            }
        }

        public static string ExecutePath
        {
            get
            {
                return AppDomain.CurrentDomain.BaseDirectory;
            }
        }
    }
}
